﻿using Metabase;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;

namespace ApplicationGUI
{

    public partial class RepositoryListForm : Form
    {
        MetabaseHandler metabaseHandler;
        public MetabaseHandler MetabaseHandler
        {
            get { return metabaseHandler; }
        }

        TreeNode baseNode;
        public RepositoryListForm()
        {
            InitializeComponent();
            Metabase_treeView.Select();
        }

        private void EditButton_Click(object sender, EventArgs e)
        {
            SettingsContextMenuStrip.Show(Edit_Button, new Point(0, Edit_Button.Height));
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void OKButton_Click(object sender, EventArgs e)
        {
            if (Metabase_treeView.SelectedNode == null) return;
            TreeNode selectedNode = Metabase_treeView.SelectedNode;
            if ((selectedNode.Tag as NodeData).NodeType != NodeTypes.Repository) return;
            if (CheckAuth())
            {
                metabaseHandler = new MetabaseHandler { dbHandler = (selectedNode.Tag as NodeData).dbHandler, MetabaseName = selectedNode.Text };
                DialogResult = DialogResult.OK;
            }
        }

        // Функция проверки авторизации
        private bool CheckAuth()
        {
            return true;
        }

        private void RepositoryListForm_Load(object sender, EventArgs e)
        {
            FillMetabaseTree();
        }

        // Процедура создает базовый нод
        private void CreateBaseNode()
        {
            NodeData nodeData = new NodeData { NodeType = NodeTypes.BaseNode };
            baseNode = new TreeNode { Text = AppResources.BaseNodeName, Tag = nodeData, ImageIndex = 0 };
            Metabase_treeView.Nodes.Add(baseNode);
            Metabase_treeView.SelectedNode = baseNode;
        }

        // Процедура заполняет список зарегистрированных репозиториев
        private void FillMetabaseTree()
        {
            Metabase_treeView.BeginUpdate();
            // Загрузим список известных нодов
            loadRepositoryInfo();
            if (Metabase_treeView.Nodes.Count == 0)
            {
                // Если список репозиториев еще не сохранялся - создадим базовый нод
                CreateBaseNode();
            }
            baseNode = Metabase_treeView.Nodes[0];
            Metabase_treeView.SelectedNode = baseNode;
            // Развернем дерево
            Metabase_treeView.Nodes[0].ExpandAll();
            // Обновим дерево
            Metabase_treeView.EndUpdate();
            Metabase_treeView.Refresh();
        }

        private void addFolderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Metabase_treeView.SelectedNode == null) return;
            TreeNode selectedNode = Metabase_treeView.SelectedNode;
            if ((selectedNode.Tag as NodeData).NodeType == NodeTypes.Repository)
            {
                selectedNode = baseNode;
            }
            NodeData nodeData = new NodeData { NodeType = NodeTypes.Folder };
            TreeNode newNode = new TreeNode { Text = AppResources.NewFolderName, Tag = nodeData, ImageIndex = (int)ImageIndexes.Folder };
            selectedNode.Nodes.Add(newNode);
            Metabase_treeView.SelectedNode = newNode;
            selectedNode.Expand();
            newNode.BeginEdit();
        }

        private void Metabase_treeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (Metabase_treeView.SelectedNode == null) return;
            TreeNode selectedNode = Metabase_treeView.SelectedNode;
            if ((selectedNode.Tag as NodeData).NodeType == NodeTypes.Repository) { OK_Button.Enabled = true; }
            else { OK_Button.Enabled = false; }
        }

        private void editMetabaseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Metabase_treeView.SelectedNode == null) return;
            TreeNode selectedNode = Metabase_treeView.SelectedNode;
            if ((selectedNode.Tag as NodeData).NodeType == NodeTypes.Repository)
            {
                // Откроем форму редактирования репозитория
                RepoPropertyForm loginForm = new RepoPropertyForm();
                // Заполним ее параметры
                NodeData nodeData = selectedNode.Tag as NodeData;
                loginForm.RepoName = selectedNode.Text;
                if (nodeData.dbHandler != null)
                {
                    loginForm.ServerName = nodeData.dbHandler.ServerName;
                    loginForm.DataBase = nodeData.dbHandler.Database;
                    loginForm.User = nodeData.dbHandler.UserName;
                    loginForm.Password = nodeData.dbHandler.Pwd;
                    loginForm.DomainAuth = nodeData.dbHandler.DomainAuth;
                }
                loginForm.ShowDialog(this);
                if (loginForm.DialogResult == DialogResult.OK)
                {
                    DBHandler dbHandler = new DBHandler { ServerName = loginForm.ServerName, Database = loginForm.DataBase, UserName = loginForm.User, Pwd = loginForm.Password, DomainAuth = loginForm.DomainAuth, Schema = "dbo" };
                    selectedNode.Tag = new NodeData { NodeType = NodeTypes.Repository, dbHandler = dbHandler };
                    selectedNode.Text = loginForm.RepoName;
                    // Проверим наличие репозитория в указанной базе
                    CheckAndCreateMetabase(dbHandler, loginForm.RepoName);
                    // Запишем информацию о составе репозиториев
                    saveRepositoryInfo();
                }
            }
            else { selectedNode.BeginEdit(); }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Metabase_treeView.SelectedNode == null) return;
            TreeNode selectedNode = Metabase_treeView.SelectedNode;
            string question;
            if ((selectedNode.Tag as NodeData).NodeType == NodeTypes.Repository) { question = AppResources.QuestionDeleteRepository; }
            else 
            {
                if ((selectedNode.Tag as NodeData).NodeType == NodeTypes.Folder) { question = AppResources.QuestionDeleteFolder; }
                else { return; }
            }
            if (MessageBox.Show(question, AppResources.Confirmation, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                Metabase_treeView.Nodes.Remove(selectedNode);
            }
            saveRepositoryInfo();
        }

        // Процедура сохранения информации о структуре доступных репозиториев
        private void saveRepositoryInfo()
        {
            ServiceProcs.SaveRepoListToXml(Metabase_treeView);
        }

        // Процедура получения сохраненной информации о структуре доступных репозиториев
        private void loadRepositoryInfo()
        {
            ServiceProcs.LoadRepoListFromXml(Metabase_treeView);
        }

        private void Metabase_treeView_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (Metabase_treeView.SelectedNode == null) return;
            if (e.Label != null) Metabase_treeView.SelectedNode.Text = e.Label;
            saveRepositoryInfo();
        }

        private void SettingsContextMenuStrip_Opened(object sender, EventArgs e)
        {
            if (Metabase_treeView.SelectedNode == null) return;
            if (Metabase_treeView.SelectedNode.Tag == null) return;
            if ((Metabase_treeView.SelectedNode.Tag as NodeData).NodeType == NodeTypes.BaseNode) deleteToolStripMenuItem.Enabled = false;
            else deleteToolStripMenuItem.Enabled = true;
        }

        private void addMetabaseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RepoPropertyForm loginForm = new RepoPropertyForm();
            loginForm.ShowDialog(this);
            if (loginForm.DialogResult == DialogResult.OK)
            {
                if (Metabase_treeView.SelectedNode == null) return;
                TreeNode selectedNode = Metabase_treeView.SelectedNode;
                if ((selectedNode.Tag as NodeData).NodeType == NodeTypes.Repository)
                {
                    selectedNode = selectedNode.Parent;
                }
                DBHandler dbHandler = new DBHandler { ServerName = loginForm.ServerName, Database = loginForm.DataBase, UserName = loginForm.User, Pwd = loginForm.Password, DomainAuth = loginForm.DomainAuth, Schema = "dbo" };
                NodeData nodeData = new NodeData { NodeType = NodeTypes.Repository, dbHandler = dbHandler };
                TreeNode newNode = new TreeNode { Text = loginForm.RepoName, Tag = nodeData, ImageIndex = (int)ImageIndexes.Repository, SelectedImageIndex = (int)ImageIndexes.Repository };
                selectedNode.Nodes.Add(newNode);
                Metabase_treeView.SelectedNode = newNode;
                // Проверим наличие репозитория в указанной базе
                CheckAndCreateMetabase(dbHandler, loginForm.RepoName);
                // Запишем информацию о составе репозиториев
                saveRepositoryInfo();
            }
        }

        // Процедура проверки и создания репозитория
        public void CheckAndCreateMetabase(DBHandler dbHandler, string metabaseName)
        {
            MetabaseHandler metabaseHandler = new MetabaseHandler { dbHandler = dbHandler, MetabaseName = metabaseName };
            Cursor.Current = Cursors.WaitCursor;
            bool connResult = metabaseHandler.dbHandler.Connect();
            if (!connResult)
            {
                MessageBox.Show(metabaseHandler.dbHandler.connectException.Message, AppResources.ErrorHeader, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                try
                {
                    metabaseHandler.InitMetabase();
                    if (!metabaseHandler.MetabaseExists) metabaseHandler.CreateMetabase(metabaseHandler.MetabaseName);
                    else metabaseHandler.UpdateMetabase(metabaseHandler.MetabaseName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(AppResources.MetabaseCreateError + ": " + ex.Message, AppResources.ErrorHeader, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            Cursor.Current = Cursors.Default;
        }
    }

    class NodeData
    {
        public NodeTypes NodeType;
        public DBHandler dbHandler;
    }
}
